﻿using System.IO;
using UnityEditor;
using UnityEngine;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System;
using UnityEngine.UI;
using Debug = UnityEngine.Debug;
using System.Linq;
using SuperScrollView;
using TMPro;

class PrefabUICodeBuilder : EditorWindow
{
    UnityEngine.Object prefab;
    //优先级
    Dictionary<Type, string> typeDic = new Dictionary<Type, string>() {

        { typeof(LoopListView2),"UnityTypes.LoopListView2"},
        { typeof(TextMeshProUGUI),"UnityTypes.TextMeshProUGUI"},
        { typeof(Button),"UnityTypes.Button"},
        
        { typeof(LoopGridView),"UnityTypes.LoopGridView"},
        { typeof(LoopStaggeredGridView),"UnityTypes.LoopStaggeredGridView"},
        { typeof(Slider),"UnityTypes.Slider"},        
        { typeof(TMP_InputField),"UnityTypes.TMP_InputField"},
        { typeof(TMP_Dropdown),"UnityTypes.TMP_Dropdown"},
        { typeof(InputField),"UnityTypes.InputField"},
        { typeof(Dropdown),"UnityTypes.Dropdown"},
        { typeof(Text),"UnityTypes.Text"},

        { typeof(Image),"UnityTypes.Image"},
        { typeof(RectTransform),"UnityTypes.RectTransform"},
    };
    //UIpanel特有的函数名称，不能作为alias
    List<String> specialFunc = new List<string>{"Close"};
    List<Type> typeList = new List<Type>();
    private void OnEnable()
    {
        typeList = typeDic.Keys.ToList();
    }
    public void OnGUI()
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("要生成的对象");
        prefab = EditorGUILayout.ObjectField(prefab, typeof(GameObject), true);
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("生成", GUILayout.ExpandWidth(true)))
        {
            if(prefab == null || !(prefab is GameObject))
            {
                Debug.LogError("请拖入正确的对象");
                return;
            }
            Transform tran = (prefab as GameObject).transform;
            Build(tran, tran, $"{prefab.name}");
            Process.Start("explorer", "Temp"); 
        }
        EditorGUILayout.EndHorizontal();
    }

    private string GetTranPath(Transform __tran, Transform parent)
    {
        string path = __tran.name;

        Transform tran = __tran.parent;
        while (tran.parent != null && tran != parent)
        {
            path = $"{tran.name}/{path}";
            tran = tran.parent;
        }
        return path;
    }
    private string GetTranAlias(string path)
    {
        string alias = System.Text.RegularExpressions.Regex.Replace(path, "[ \\[ \\] \\^ \\-_*×――(^)（^）/$%~!@#$…&%￥—+=<>《》!！??？:：•`·、。，；,.;\"‘’“”-]", "_");
        foreach (var item in specialFunc)
        {
            if(alias.Equals(item))
            {
                alias = "_" + alias;
            }
        }
        return alias;
    }
    private string GetNodeInfo(Transform __tran,Transform parent,List<string> funcList)
    {
        string path = GetTranPath(__tran, parent);
        string alias = GetTranAlias(path);

        string extra = string.Empty;
        Type t = GetTranType(__tran);
        if(t == null)
        {
            Debug.LogError($"{path}未定义dicType");
            return string.Empty;
        }
        //btn
        string func = $"Click{alias}";
        if (t == typeof(Button))
        {
            extra = $"onClick = \"{func}\"";
            funcList.Add(func);
        }        
        return $"       {{Path = \"{path}\",Alias= \"{alias}\",Type={typeDic[t]},{extra}}},";
    }

    string GetFuncInfo(string ClassName, List<string> funcList)
    {
        string funcStr = string.Empty;
        foreach (var item in funcList)
        {
            funcStr += $"function {ClassName}:{item}()\nend\n\n";
        }
        return funcStr;
    }
    void BuildListView(Transform tran,Transform parent)
    {
        Transform tmpTran = tran.Find("Viewport/Content");
        string alias = GetTranAlias(GetTranPath(tran, parent));
        if (tmpTran == null)
        {
            Debug.LogError($"{alias}  ScrollView缺少Viewport/Content");
        }
        else
        {
            if (tran.childCount == 0)
            {
                Debug.LogError($"{alias}  Content无子节点");
            }
            else
            {
                Transform child = tmpTran.GetChild(0);
                Build(child, child, prefab.name +"_"+alias, 0);
            }
        }
    }
    private void Build(Transform self, Transform refer_parent, string ClassName,int depth = 0, StringBuilder ClassBuilder = null, List<string> funcList = null)
    {
        if (depth == 0)
        {
            funcList = new List<string>();
            funcList.Add("OnShow");
            funcList.Add("OnClose");
            ClassBuilder = new StringBuilder();
            ClassBuilder.AppendLine($"---@class {ClassName} :UIPanel\nlocal StringConfig = require(\"Unity.Config.StringConfig\")\nlocal {ClassName}, super = _G.UIPanelClass(StringConfig.{ClassName})\n" +
                $"{ClassName}.setting ={{\n" +
                $"  showType = emPanelShowType.NormalLayer,\n" +
                $"  abName = \"xxxx\",\n" +
                $"  resName = \"{ClassName}\",\n" +
                $"  elements = {{ \n");
        }

        for (int i = 0; i < self.childCount; i++)
        {
            Transform tran = self.GetChild(i);
            if (!tran.name.EndsWith(EditorHelper.ignoreAllName))
            {
                if (!tran.name.EndsWith(EditorHelper.ignoreName))
                {
                    ClassBuilder.AppendLine(GetNodeInfo(tran, refer_parent, funcList));
                }
                if (tran.GetComponent<ScrollRect>() != null)
                {
                    BuildListView(tran, self);
                }
                else
                {
                    Build(tran, refer_parent, string.Empty, depth + 1, ClassBuilder, funcList);
                }
            }
        }

        if(depth == 0)
        {
            ClassBuilder.AppendLine("   }\n}\n");
            ClassBuilder.AppendLine(GetFuncInfo(ClassName, funcList));
            ClassBuilder.AppendLine($"return {ClassName}");
            string fileName = $"Temp\\{ClassName}.lua";
            File.WriteAllText(fileName, ClassBuilder.ToString());
        }
    }

    Type GetTranType(Transform __tran)
    {
        foreach (var item in typeList)
        {
            if (__tran.GetComponent(item))
            {
                return item;
            }
        }
        return null;
    }
}
